package cn.com.dragonpass.psystem.common.util;

import cn.com.dragonpass.common.base.BussinessException;
import cn.com.dragonpass.common.utils.StringUtils;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * 汇率模板
 */
public class DynamicExcelUtil {


    public static void exportDynamicExcel(List<List<String>> headList, List<List<String>> dataList, String title, String sheetName, String fileName, HttpServletResponse response)  {
        try {
            setResponse(title, fileName, response);

            HorizontalCellStyleStrategy horizontalCellStyleStrategy = getCellStyleStrategy();
            
            EasyExcel.write(response.getOutputStream()).head(headList)
                    .registerWriteHandler(horizontalCellStyleStrategy)
                    .registerWriteHandler(new CustomRowWriteHandler(0,0,0,2))
                    .registerWriteHandler(new SimpleColumnWidthStyleStrategy(30))
                    .sheet(sheetName)
                    .doWrite(dataList);




        }catch (IOException e){
            e.printStackTrace();
            throw new BussinessException("excel.export.fail");
        }

    }


    /**
     * 自定义样式
     * @return
     */
    private static HorizontalCellStyleStrategy getCellStyleStrategy() {
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景设置为红色
        //headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short)11);
        headWriteCellStyle.setWriteFont(headWriteFont);
        headWriteFont.setBold(false);
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.TOP);
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
        headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
        //contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        // 背景绿色
        //  contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());
        WriteFont contentWriteFont = new WriteFont();
        // 字体大小
        contentWriteFont.setFontHeightInPoints((short)11);
        contentWriteCellStyle.setWriteFont(contentWriteFont);

        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        contentWriteCellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
        contentWriteCellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        return horizontalCellStyleStrategy;
    }


    /**
     * 自定义行和对应合并
     */
    public static class CustomRowWriteHandler implements RowWriteHandler {



        private int firstRow;
        private int lastRow;
        private int firstCol;
        private int lastCol;


        public CustomRowWriteHandler(int firstRow, int lastRow, int firstCol, int lastCol) {
            this.firstRow = firstRow;
            this.lastRow = lastRow;
            this.firstCol = firstCol;
            this.lastCol = lastCol;
        }

        @Override
        public void beforeRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Integer integer, Integer integer1, Boolean aBoolean) {
            //   System.out.println("..............");
        }

        @Override
        public void afterRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer integer, Boolean aBoolean) {
            // System.out.println("..............*********");
        }

        @Override
        public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,
                                    Integer relativeRowIndex, Boolean isHead) {

            //  System.out.println(relativeRowIndex+"------->"+row.getRowNum());
            // 在这里编写你的自定义逻辑
            // 例如，给每一行添加一个公共的背景颜色
            // row.getCell(0).getCellStyle().setFillForegroundColor(IndexedColors.YELLOW.getIndex());
            // row.getCell(0).getCellStyle().setFillPattern(FillPatternType.SOLID_FOREGROUND);


            if ( relativeRowIndex.equals(firstRow)&&row.getRowNum()==0) {
                CellRangeAddress cellRangeAddress = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
                writeSheetHolder.getSheet().addMergedRegion(cellRangeAddress);
            }
            if (relativeRowIndex == 0 &&row.getRowNum()==0) {
                row.setHeight((short) 2500);
            }else{
                Cell cell = row.getCell(0);
                CellStyle cellStyle = cell.getCellStyle();
                cellStyle.setWrapText(true);
                cellStyle.setBorderRight(BorderStyle.THIN);
                cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
                cell.setCellStyle(cellStyle);
            }
        }
    }

    public static void setResponse(String title, String fileName, HttpServletResponse response) throws UnsupportedEncodingException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        if (StringUtils.isBlank(fileName)) {
            fileName = URLEncoder.encode(title + "_" + DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.now()), "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        } else {
            response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") +".xlsx");
        }
    }
}

-------------
 /**
     * 模版下载
     * @param response
     */
    @PostMapping("/exportTemple")
    public void exportCusSetData( HttpServletResponse response){

        ExchageRateCurrencyDto.CurrencyDto.Input in=new ExchageRateCurrencyDto.CurrencyDto.Input();
        List<ExchageRateCurrencyDto.CurrencyDto.Output> exchangeList = Asserts.assertStateOk(settleExchageRateCurrencyControllerFeign.list(in));
        String fileName="汇率货币模板";
        List<List<String>> data = new ArrayList<>();
        data.add(Arrays.asList("币种编码" ,"币种名称 ","汇率 "));
        if (CollectionUtils.isNotEmpty(exchangeList)) {
            for (ExchageRateCurrencyDto.CurrencyDto.Output output : exchangeList) {
                data.add(Arrays.asList(output.getCurrency(),output.getCurrencyName(),""));
            }

        }
        DynamicExcelUtil.exportDynamicExcel(head(),data,null,"汇率货币",fileName,response);


    }

     private static  List<List<String>> head() {
        List<List<String>> list = new ArrayList<List<String>>();
        List<String> head0 = new ArrayList<String>();
        String msg="1、导入字段说明\n" +
                "（1）币种编码：必填，需大写，如CNY、USD；\n" +
                "（2）币种名称：如人民币、美元等；\n" +
                "（3）汇率：必填，支持小数点后四位，不足四位补0，多余四位采用四舍五入；\n" +
                "2、若对应币种汇率无需更新，模板需要删除该币种数据；\n" +
                "3、以人民币为本位币导入汇率数据；";
        head0.add(msg);
        List<String> head1 = new ArrayList<String>();
        head1.add("货币" );
        List<String> head2 = new ArrayList<String>();
        head2.add("汇率");
        list.add(head0);
        list.add(head1);
        list.add(head2);
        return list;
    }


---
 <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.1.1</version>
            <exclusions>
                <exclusion>
                    <groupId>cglib</groupId>
                    <artifactId>cglib</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
